Object.defineProperty(global, '__stack', {
    get: function () {
        var orig = Error.prepareStackTrace;
        Error.prepareStackTrace = function (_, stack) {
            return stack;
        };
        var err = new Error;
        Error.captureStackTrace(err, arguments.callee);
        var stack = err.stack;
        Error.prepareStackTrace = orig;
        return stack;
    }
});

Object.defineProperty(global, '__line', {
    get: function () {
        return __stack[1].getLineNumber();
    }
});

const log4js = require('log4js');
log4js.configure({
    appenders: {
        stdout: {
            type: 'stdout'
        }
    },
    categories: {
        default: {
            appenders: ['stdout'], level: 'debug'
        }
    }
})

const logger = log4js.getLogger(),
	CDP = require('chrome-remote-interface'),
	fs = require('fs')

logger.debug('[' + __filename + ':' + __line + ']', 'start')
CDP({
	port: 9222,
	target(targets) {
		for (var i = 0; i < targets.length; i++) {
			if (targets[i].url.indexOf('https://bs.ghbank.com.cn/app/course/detail/') == 0) {
				return targets[i]
			}
		}
	}
}).then(client => {
	const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client
    Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
		logger.debug('[' + __filename + ':' + __line + ']', 'connect')
        selectPaper(client, 11, 12).then(result => {
			process.exit(0)
		})
    }).catch(err => {
        logger.error('[' + __filename + ':' + __line + ']', err)
    })
})

async function selectPaper(client, i, endIdx) {
	const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client
	var {result} = await Runtime.evaluate({expression: 'document.querySelectorAll(".wbtj.mr20").length'})
	if (i >= result.value || i >= endIdx)
		return Promise.resolve()
    await Runtime.evaluate({expression: 'document.querySelectorAll(".wbtj.mr20")['+i+'].click()'})
	return new Promise(resolve => {
		setTimeout(() => {
			selectQuestion(0, async () => {
				await Runtime.evaluate({expression: 'document.querySelectorAll(".wbtj.mr20")['+i+'].click()'})
			}, i).then(result => {
				selectPaper(client, i + 1, endIdx).then(result => {
					resolve(result)
				})
			})
		}, 1000)
	})
}

async function selectQuestion(idx, preHook, paper, endIdx) {
	endIdx = endIdx || 1
	return new Promise(resolve => {
		CDP.List({
			port: 9222
		}, (err, targets) => {
			for (let i = 0; i < targets.length; i++) {
				if (targets[i].url.indexOf('https://bs.ghbank.com.cn/servlet/qdbAction') == 0) {
					CDP({
						port: 9222,
						target: targets[i]
					}).then(client => {
						const {
							Network,
							Page,
							DOM,
							Runtime,
							Emulation
						} = client
						Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
							let sleepCnt = 0
							while(1) {
								var {result} = await Runtime.evaluate({expression: 'document.querySelectorAll(".TextBtn").length'})
								if (result.value < endIdx) {
									sleepCnt++
									logger.debug('[' + __filename + ':' + __line + ']', 'sleepCnt=' + sleepCnt, 'result.value=' + result.value, 'endIdx=' + endIdx)
									if (sleepCnt > 60) {
										await Runtime.evaluate({expression: 'window.close()'})
										preHook()
										setTimeout(() => {
											selectQuestion(idx, preHook, paper, endIdx).then(result => {
												resolve(result)
											})
										}, 1000)
										return
									}
									await sleep(1)
								} else {
									endIdx = result.value
									break
								}
							}
							if (idx >= endIdx) {
								await Runtime.evaluate({expression: 'window.close()'})
								logger.debug('[' + __filename + ':' + __line + ']', idx, endIdx)
								fs.writeFileSync('C:\\Users\\ye\\Desktop\\第一季度第'+paper+'套.txt', '\n', {
									flag : 'a'
								})
								resolve()
								return
							}
							await Runtime.evaluate({expression: 'document.querySelectorAll(".TextBtn")['+idx+'].click()'})
							var question = ''
							while(!question) {
								await sleep(1)
								var {result} = await Runtime.evaluate({expression: 'document.querySelectorAll(".Text")[0].innerText'})
								question = result.value
							}
							var {result} = await Runtime.evaluate({expression: 'document.querySelectorAll(".Correct").length'})
							var answer = ''
							var cnt = result.value
							for (let i = 0; i < cnt; i++) {
								var {result} = await Runtime.evaluate({expression: 'document.querySelectorAll(".Correct")['+i+'].innerText'})
								if (answer != '')
									answer += '; '
								answer += result.value
							}
							await Runtime.evaluate({expression: 'window.close()'})
							logger.debug('[' + __filename + ':' + __line + ']', (idx + 1) + '、' + question + '(' + answer + ')')
							fs.writeFileSync('C:\\Users\\ye\\Desktop\\第一季度第'+paper+'套.txt', (idx + 1) + '、' + question + '(' + answer + ')\n', {
								flag : idx == 0 ? 'w' : 'a'
							})
							preHook()
							setTimeout(() => {
								selectQuestion(idx + 1, preHook, paper, endIdx).then(result => {
									resolve(result)
								})
							}, 1000)
						}).catch(err => {
							logger.error('[' + __filename + ':' + __line + ']', err)
						})
					})
					return
				}
			}
			setTimeout(() => {
				selectQuestion(idx, preHook, paper, endIdx).then(result => {
					resolve(result)
				})
			}, 1000)
		})
	})
}

function sleep(second) {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve()
		}, second * 1000)
	})
}